package com.enzi.webclient.restHandlers;

import com.enzi.webclient.beans.MethodInfo;
import com.enzi.webclient.beans.ServerInfo;
import com.enzi.webclient.interfaces.RestHandler;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * @Author: enzi.cheng
 * @Date: 2019/1/15 11:26
 * @Description:
 */
public class WebClientRestHandler implements RestHandler {

    private WebClient clent;
    private RestTemplate restTemplate;

    /**
     * 初始化webclient
     *
     * @param serverInfo
     */
    @Override
    public void init(ServerInfo serverInfo) {
        this.clent = WebClient.create(serverInfo.getUrl());
    }

    /**
     * 处理请求
     *
     * @param methodInfo
     * @return
     */
    @Override
    public Object invokeRest(MethodInfo methodInfo) {
        //返回结果
        Object result = null;
        WebClient.ResponseSpec retrieve = null;

        WebClient.RequestBodySpec request = this.clent
                //请求方法
                .method(methodInfo.getMethod())
                //请求url
                .uri(methodInfo.getUrl(), methodInfo.getParams())
                //
                .headers(httpHeaders -> {
                    httpHeaders.add("Authorization", "1000002");
                })
                .accept(MediaType.APPLICATION_JSON);
        if (methodInfo.getBody() != null) {
            retrieve = request.body(methodInfo.getBody(), methodInfo.getBodyElementType()).retrieve();
        } else {
            retrieve = request.retrieve();
        }
        //处理异常
        retrieve.onStatus(status -> status.value() == 404, response -> Mono.just(new RuntimeException("Not Found")));

        //发出请求

        if (methodInfo.isReturnFlux()) {
            result = retrieve.bodyToFlux(methodInfo.getReturnElementType());
        } else {
            result = retrieve.bodyToMono(methodInfo.getReturnElementType());
        }


        return result;
    }
}
